﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Text;
using System.Threading;
using System.Web.UI;

using Eneta.Portal.Forum.Controls.Base;
using Eneta.Portal.Forum.Core.Service.Application;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebPartPages;
using WebPart = System.Web.UI.WebControls.WebParts.WebPart;

namespace Eneta.Portal.Forum.WebParts
{
    public class EnetaForumWebPart : WebPart
    {
        private readonly List<Exception> _errorList = new List<Exception>();

        public EnetaForumWebPart()
        {
            DateFormat = "F";
            Name = "Discussion Forums";
        }

        // Methods
        public void AddError(Exception ex)
        {
            if (ex == null)
                return;
            ErrorList.Add(ex);
        }

        protected override void CreateChildControls()
        {
            //using(SPSite site = new SPSite("http://mossdev-public/"))
            //using (var web = site.OpenWeb("/forum/"))
            //{                
            //    foreach (SPField fld in web.Fields)
            //    {
            //        HttpContext.Current.Response.Write(fld.Title + ": " + fld.Id.ToString() + "<br/>");
            //    }
            //}

            //return;
            SharePointForumControls viewForums;
            try
            {
                viewForums = (SharePointForumControls)Enum.Parse(typeof(SharePointForumControls), Page.Request.QueryString["control"], true);
            }
            catch
            {
                viewForums = SharePointForumControls.ViewForums;
            }

            var sec = new SPSecurity.CodeToRunElevated(delegate
            {
                if (viewForums == SharePointForumControls.ViewForums)
                {
                    var control = Page.LoadControl("~/_controltemplates/ForumsMainViewControl.ascx");
                    Controls.Add(control);
                }
                else if (viewForums == SharePointForumControls.ViewTopics)
                {
                    var control = Page.LoadControl("~/_controltemplates/ForumsTopicsViewControl.ascx");
                    Controls.Add(control);
                }
                else if (viewForums == SharePointForumControls.ViewMessages)
                {
                    var control = Page.LoadControl("~/_controltemplates/ForumsPostsViewControl.ascx");
                    Controls.Add(control);
                }
                else if (viewForums == SharePointForumControls.UpdateMessage)
                {
                    var control = Page.LoadControl("~/_controltemplates/ForumsUpdateMessage.ascx");
                    Controls.Add(control);
                }
                else
                {
                    /*if (viewForums == SharePointForumControls.ViewMessages)
                     {
                         var control = Page.LoadControl("~/_controltemplates/ForumsPostsViewControl.ascx");
                         Controls.Add(control);
                     }*/
                    var child = CreateDynamicForumControl(viewForums);
                    if (child != null)
                    {
                        Controls.Add(child);
                        Controls.Add(new LiteralControl("."));
                    }
                }
            });
            SPSecurity.RunWithElevatedPrivileges(sec);
        }

        private Control CreateDynamicForumControl(SharePointForumControls childControl)
        {
            BaseForumControl control = null;
            try
            {
                control = Activator.CreateInstance(Type.GetType(string.Format("{0}.{1}", "Eneta.Portal.Forum.Controls", childControl))) as BaseForumControl;
                if (control != null)
                    control.WebPartParent = this;
            }
            catch (Exception exception)
            {
                AddError(exception);
            }
            return control;
        }

        private void InitializeApplication()
        {
            //var query = new UrlQuery(Page.Request.Url.ToString());
            //ForumApplication.Instance.BasePath = SPEncode.UrlEncodeAsUrl(query.Url);
            //ForumApplication.Instance.Title = Name;
            //ForumApplication.Instance.ForumCache = Page.Cache;

            // GPF-3 + block
            //ForumApplication.Instance.SpUser = SPControl.GetContextWeb(Context).CurrentUser;
            //ForumApplication.Instance.AppPoolUser = SPControl.GetContextSite(Context).OpenWeb().CurrentUser;
            //ForumApplication.Instance.SpWeb = SPControl.GetContextSite(Context).OpenWeb();

            var siteId = SPContext.Current.Web.Site.ID;
            var webId = SPContext.Current.Web.ID;
            var loginName = string.Empty;

            if (SPContext.Current.Web.CurrentUser != null)
                loginName = SPContext.Current.Web.CurrentUser.LoginName;


            //var sec = new SPSecurity.CodeToRunElevated(delegate
            //    {
            //        var site = new SPSite(siteId);
            //        var web = site.OpenWeb(webId);

            //        if(!string.IsNullOrEmpty(loginName))
            //            ForumApplication.Instance.SpUser = web.SiteUsers[loginName];
            //        ForumApplication.Instance.AppPoolUser = web.CurrentUser;
            //        ForumApplication.Instance.SpWeb = web;
            //    });
            //SPSecurity.RunWithElevatedPrivileges(sec);
        }

        public string LoadResource(string id)
        {
            return id;
        }

        protected override void OnInit(EventArgs e)
        {
            //using (Identity.ImpersonateAppPool())
            //{
            InitializeApplication();
            //CheckAndBuildLists();
            //}
        }

        protected override void OnLoad(EventArgs e)
        {
        }

        public void PersistProperties()
        {
            try
            {
                //ForumApplication.Instance.SpWeb.AllowUnsafeUpdates = true;
                //base.SaveProperties = true;
            }
            catch (Exception exception)
            {
                AddError(exception);
            }
        }

        private void RenderError(TextWriter output)
        {
            var builder = new StringBuilder();
            foreach (var exception in ErrorList)
            {
                builder.AppendFormat("{0}<br>", exception);
                var ex = exception;
                while (ex.InnerException != null)
                {
                    ex = ex.InnerException;
                    builder.Append("<br/>");
                    builder.Append(ex.ToString());
                }
            }
            output.WriteLine("An error has occurred with the Forums Web Part.");
            output.WriteLine("See the details below for more information.</p>");
            output.WriteLine("<div class=\"ms-alerttext\">{0}</div>", builder);
            output.WriteLine("</p><strong><a href=\"mailto:{0}?Subject=Forum Error&Body={1}\">Email error information to support</a></strong></p>", "bsimser@shaw.ca", builder);
            output.WriteLine("<a href=\"{1}\">Return to {0} Home</a>", Name, ForumApplication.Instance.GetLink(SharePointForumControls.ViewForums));
        }

        public void RenderError(HtmlTextWriter output, Exception ex)
        {
            AddError(ex);
            RenderError(output);
        }

        protected override void Render(HtmlTextWriter output)
        {
            if (output != null)
            {
                try
                {
                    EnsureChildControls();
                    if (IsValid)
                    {
                        //using (Identity.ImpersonateAppPool())
                        //{
                        foreach (Control control in Controls)
                        {
                            control.RenderControl(output);
                        }
                        return;
                        //}
                    }
                    RenderError(output);
                }
                catch (ThreadAbortException)
                {
                }
                catch (Exception exception)
                {
                    RenderError(output, exception);
                }
            }
        }

        // Properties
        [Description("Format for date dislays in your discussion forum."), DefaultValue("F"), WebPartStorage((Storage)2), FriendlyName("Date Format"), Category("Forum Properties"), Browsable(false)]
        public string DateFormat { get; set; }

        public List<Exception> ErrorList
        {
            get
            {
                return _errorList;
            }
        }

        [Description("Number of forums in this site."), FriendlyName("Forum Count"), Browsable(false),
         Category("Forum Properties"), DefaultValue(0), WebPartStorage((Storage)2)]
        public int ForumCount { get; set; }

        public bool IsValid
        {
            get
            {
                return (ErrorList.Count == 0);
            }
        }

        [Category("Forum Properties"), DefaultValue("Discussion Forums"), WebPartStorage((Storage)2), FriendlyName("Forum Name"), Description("Display name for your discussion forum."), Browsable(false)]
        public string Name { get; set; }

        [DefaultValue(0), Browsable(false), Category("Forum Properties"), WebPartStorage((Storage)2),
         FriendlyName("Post Count"), Description("Number of posts in this forum.")]
        public int PostCount { get; set; }

        [Browsable(false), Description("Number of topics in this forum."), Category("Forum Properties"), DefaultValue(0)
        , WebPartStorage((Storage)2), FriendlyName("Topic Count")]
        public int TopicCount { get; set; }
    }
}
